package com.topnav.mc.listener;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.js.lib.utils.DateUtils;
import com.topnav.mc.admin.entity.*;
import com.topnav.mc.admin.entity.bean.DeviceAlarmBean;
import com.topnav.mc.admin.entity.enums.DeviceAlarmCate;
import com.topnav.mc.admin.entity.enums.DeviceAlarmMethod;
import com.topnav.mc.admin.entity.param.DeviceAlarmParam;
import com.topnav.mc.admin.entity.param.DeviceParam;
import com.topnav.mc.admin.service.*;
import com.topnav.mc.listener.bean.DeviceAlarmMessage;
import com.topnav.mc.listener.bean.GPSMsgInfo;
import com.topnav.mc.lock.SyncLock;
import com.topnav.mc.position.PositionInfo;
import com.topnav.mc.position.PositionUtil;
import com.topnav.mc.sse.DeviceAlarmQueue;
import com.topnav.mc.sse.EnumSseMessageType;
import com.topnav.mc.sse.MessageBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * @Author: kenny
 * @Date: 2023/10/10 18:28
 */
@Component
@Slf4j
public class RedisAlarmMsgListener implements MessageListener {
    @Autowired
    private RedisGpsMsgListener redisGpsMsgListener;
    @Autowired
    private IDeviceService deviceService;
    @Autowired
    private IDeviceChannelService channelService;
    @Autowired
    private IDeviceAlarmService deviceAlarmService;
    @Autowired
    private IUserService userService;
    @Autowired
    private IOrganizationService organizationService;
    @Autowired
    private DeviceAlarmQueue deviceAlarmQueue;
    @Autowired
    private PositionUtil positionUtil;


    private String fmt = "yyyy-MM-dd HH:mm:ss";
    private ConcurrentLinkedQueue<Message> taskQueue = new ConcurrentLinkedQueue<>();

    @Override
    public void onMessage(@NotNull Message message, byte[] bytes) {
        log.info("收到来自REDIS的ALARM通知： {}", new String(message.getBody()));
        taskQueue.offer(message);
        this.consusAlarm();
    }

    @Async("taskExecutor")
    @SyncLock(key="RedisAlarmMsgListener-consusAlarm-LOCK",dueSec = 3*60,errorUnLock = true)
    public void consusAlarm(){
        // 保存数据
        // 分属部门和人
        // 然后推送只推送给管理员
        while (!taskQueue.isEmpty()) {
            try{
                Message msg = taskQueue.poll();
                DeviceAlarmMessage deviceAlarmMessage = JSON.parseObject(msg.getBody(), DeviceAlarmMessage.class);

                if (String.valueOf(DeviceAlarmMethod.GPS.code).equals(deviceAlarmMessage.getAlarmMethod())){
                    //GPS 报送， 只保存GPS，不保存为报警，不推送
                    GPSMsgInfo gpsMsgInfo = new GPSMsgInfo();
                    gpsMsgInfo.setSerial(deviceAlarmMessage.getDeviceCode());
                    gpsMsgInfo.setCode(deviceAlarmMessage.getChannelCode());
                    gpsMsgInfo.setLongitude(deviceAlarmMessage.getLongitude());
                    gpsMsgInfo.setLatitude(deviceAlarmMessage.getLatitude());
                    gpsMsgInfo.setTime(deviceAlarmMessage.getTime());
                    redisGpsMsgListener.alarmGps(gpsMsgInfo);
                }else{
                    //其它报警
                    Device device = null;
                    if ((device = deviceService.getFromCache(deviceAlarmMessage.getDeviceCode())) == null){
                        continue;
                    }

                    DeviceAlarm deviceAlarm = new DeviceAlarm();
                    deviceAlarm.setDeviceId(device.getId());
                    DeviceChannel dc = channelService.getChannelFromDevAndChnCode(device.getId(),deviceAlarmMessage.getChannelCode());
                    if (dc != null){
                        deviceAlarm.setChannelId(dc.getId());
                    }
                    deviceAlarm.setAlarmMethod(deviceAlarmMessage.getAlarmMethod());
                    //类型为SOS
                    deviceAlarm.setAlarmCate(DeviceAlarmCate.SOS.getCode());
                    deviceAlarm.setAlarmPriority(deviceAlarmMessage.getAlarmPriority());
                    if (!StringUtils.isEmpty(deviceAlarmMessage.getTime())){
                        deviceAlarm.setAlarmTime(DateUtils.parse(deviceAlarmMessage.getTime(),fmt));
                    }else{
                        deviceAlarm.setAlarmTime(new Date());
                    }
                    deviceAlarm.setCreateTime(new Date());
                    deviceAlarm.setUpdateTime(new Date());

                    deviceAlarm.setAlarmDescription(deviceAlarmMessage.getAlarmDescription());
                    deviceAlarm.setLongitude(deviceAlarmMessage.getLongitude());
                    deviceAlarm.setLatitude(deviceAlarmMessage.getLatitude());
                    if (deviceAlarm.getLongitude() == null || deviceAlarm.getLongitude() == 0.0){
                        //报警不带定位则限当前的
                        PositionInfo positionInfo = positionUtil.getCurrentPosition(deviceAlarmMessage.getDeviceCode());
                        if (positionInfo != null){
                            deviceAlarm.setLongitude(positionInfo.getLongitude());
                            deviceAlarm.setLatitude(positionInfo.getLatitude());
                        }
                    }

                    if (deviceAlarm.getAlarmType() != null){
                        deviceAlarm.setAlarmType(deviceAlarmMessage.getAlarmType());
                    }
                    deviceAlarmService.save(deviceAlarm);
                    Thread.sleep(50L);
                    //加入推送队列
                    if (device.getUserId() != null || device.getOrgId() != null){
                        //查询完整信息
                        QueryWrapper<DeviceAlarmParam> queryWrapper = new QueryWrapper<DeviceAlarmParam>().eq("a.id",deviceAlarm.getId());
                        DeviceAlarmBean deviceAlarmBean = deviceAlarmService.getOneInfo(queryWrapper,false);

                        MessageBean messageBean = new MessageBean(EnumSseMessageType.ALARM_NOTIFY);
                        messageBean.setMessage(deviceAlarmBean);

                        if (device.getUserId() != null){
                            User user = userService.getById(device.getUserId());
                            messageBean.setUserId(user.getId());
                            messageBean.setUserName(user.getName());
                        }
                        if (device.getOrgId() != null){
                            Organization organization = organizationService.getById(device.getOrgId());
                            messageBean.setOrgId(organization.getId());
                            messageBean.setOrgPath(organization.getPath());
                        }
                        deviceAlarmQueue.offer(messageBean);
                    }
                }
                Thread.sleep(5L);
            }catch (Exception e){
                log.error(" >>>>>> 处理ALARM通知 异常：{}",e.toString());
                continue;
            }
        }
    }


}
